import md5 from 'md5';
import axios from 'axios';
import moment from 'moment';
import config from '../configuration.js';
import { v4 as uuidv4 } from 'uuid';



/*乐收赢请求基地址 */
const baseUrl = 'https://open.gdyfsk.com/yfpay';
/** 乐收赢机构号 */
const inst_no = '900246';
/**乐收赢机构密钥 */
const inst_key = '7ee66094b9f54cb1ba32a95dbbf80e97';
//乐收赢文档地址：https://www.showdoc.com.cn/leshouying

/** 乐收赢商户号 */
const main_mch_no = '852505050001';

const test_openid = 'olxGY7XgczWJZXnCOwkwSmU4jaUI';



function makeSign(data, secret=inst_key) {
    let keys = Object.keys(data).sort();
    let paramStr = '';
    for (let index = 0; index < keys.length; index++) {
        if (keys[index] == 'sign') continue;
        let element = keys[index];
        if (paramStr.length > 0) {
            paramStr += '&';
        }
        paramStr += `${element}=${data[element]}`;
    }
    paramStr += `&key=${secret}`;
    console.log('加密前明文', paramStr);
    return md5(paramStr);
}
async function post(url, data, describe) {
    try {
        let res = await axios.post(url, data);
        let response = res.data ? res.data : {};
        console.debug(`${describe}  请求地址:${url} 请求参数 ${JSON.stringify(data)}  返回状态码:${res.status}  返回内容:${JSON.stringify(response)}`);
        return response;
    } catch (error) {
        console.error(`${describe}出错,错误原因:'` + error.message, `请求地址:${url},请求参数:${JSON.stringify(data)}`);
        return { errMsg: error.message };
    }
}
//生成毫秒时间戳加六位随机数的字符串
function generateTraceNo() {
    return moment().format('YYYYMMDDHHmmssSSS') + Math.floor(Math.random() * 1000000);
}


//小程序支付
async function applet_pay(pay_trace_no,mch_no,total_amount, openid, order_body) {
    let url = `${baseUrl}/v3/minipay`;
    let data = {
        inst_no,
        mch_no,
        pay_type: '400',
        appid: config.applet_param.APPID,
        pay_trace_no,
        pay_time: moment().format('YYYYMMDDHHmmss'),
        total_amount,
        open_id: openid,
        order_body,
        notify_url:`${config.pay_notify_url}/api/lsy/notify`, //回调地址
    }
    data.sign = makeSign(data, inst_key);
    let res = await post(url, data, '小程序支付');
    return res;
}
/**
 * 乐收赢余额分账支付
 * @param {*} trade_no  请求流水号
 * @param {*} share_array 分账数组结构  { share_mch: '被分账方商户号', share_amount: '分账金额 单位分' }
 * @param {*} amount  分账总金额
 * @param {*} attach  附加数据
 * @param {*} isRec  是否重试
 * @param {*} retry_id  重试记录id
 * @returns 
 */
async function balancePay(trade_no, share_array, amount, attach="", isRec = false, retry_id = null) {
    let url = `${baseUrl}/v3/yupay`;
    let data = {
        inst_no,
        mch_no: main_mch_no,
        pay_trace_no: trade_no,
        pay_time: moment().format('YYYYMMDDHHmmss'),
        attach: attach,
        total_amount: amount.toString(),
        share_type: '1',
        share_detail: JSON.stringify({
            share_count: share_array.length,
            share_fee_mch: main_mch_no,  //分出方承担手续费  实际为0
            share_array
        }),
    };
    let sign = makeSign(data);
    data.sign = sign;
    try {
        let logString = `乐收赢_余额支付(分账)`;
        if (isRec) {
            logString += `重试`;
        }

        let res = await post(url, data, logString);
        if (res.return_code == 'SUCCESS') {
            if (isRec) {
                //清除成功的记录
                await mysqlHelper.deleteRow(`balance_pay_try`, { id:retry_id});
            }
            return {code:0,msg:'支付成功'};
        } else {
            if (res.return_code == 'PAY_IN_PROCESS') {
                logger.warn(`余额支付异常：`, res.return_msg, `入参：`, data, `响应：`, res);
            } else if (res.return_code == 'PAY_FAIL') {
                logger.error(`余额支付失败：`, res.return_msg, `入参：`, data, `响应：`, res);
            }

            if (!isRec) {
                //加入记录第二天重试
                await mysqlHelper.create('balance_pay_try', {
                    id: uuidv4(),
                    error_msg: res.return_msg,
                    data: JSON.stringify({ mch_no, trade_no, attach, amount, share_array }),
                    fail_count: 0,
                    create_time: moment().format('YYYY-MM-DD'),
                });
            } else {
                await mysqlHelper.query(`update balance_pay_try set fail_count=fail_count+1,error_msg='${res.return_msg}' where id=${retry_id}`);
            }
            logger.error(`余额支付失败：`, `入参：`, data, 'error', res.return_msg);
            return {code:1,msg:res.return_msg};
        }
    } catch (error) {
        logger.error(`余额支付失败：`, `入参：`, data, 'error', error.message);
        //重试
        if (!isRec) {
            //加入记录第二天重试
            await mysqlHelper.create('balance_pay_try', {
                id: uuidv4(),
                error_msg: res.return_msg,
                data: JSON.stringify({ mch_no, trade_no, attach, amount, share_array }),
                fail_count: 0,
                create_time: moment().format('YYYY-MM-DD'),
            });
        } else {
            await mysqlHelper.query(`update balance_pay_try set fail_count=fail_count+1,error_msg='${res.return_msg}' where id=${retry_id}`);
        }
        return {code:1,msg:error.message};
    }
}

/**
 * 余额分账状态查询
 * @param {*} pay_trace_no 原分账流水号
 * @param {*} share_mch_no 被分账商户号
 * @returns 
 */
async function balancePayStatus(pay_trace_no,share_mch_no) {
    let url = `${baseUrl}/v3/yupayQuery`;
    let data = {
        inst_no,
        mch_no: share_mch_no,
        query_trace_no: uuidv4().replace(/-/g, ''),
        pay_trace_no,
    };
    let sign = makeSign(data);
    data.sign = sign;
    try {
        let res = await post(url, data, '乐收赢_余额支付(查询)');
        if (res.return_code == 'SUCCESS' && res?.result_code == 'PAY_SUCCESS') {
            return {code:0,msg:'分账成功'};
        } else {
            return {code:1,msg:res.return_msg};
        }
    } catch (error) {
        return {code:1,msg:error.message};
    }
}
/**
 * 余额支付退款
 * @param {*} pay_trace_no 退款流水号
 * @param {*} org_pay_trace_no 原分账支付流水号
 * @param {*} share_mch_no 原被分账商户号
 * @param {*} amount 退款金额 单位分
 * @returns 
 */
async function balancePayRefund(pay_trace_no,org_pay_trace_no,share_mch_no,amount) {
    let url = `${baseUrl}/v3/refundYupay`;
    let data = {
        inst_no,
        mch_no: share_mch_no,
        pay_trace_no,
        pay_time: moment().format('YYYYMMDDHHmmss'),
        org_pay_trace_no,
        total_amount: amount
    };
    let sign = makeSign(data);
    data.sign = sign;
    try {
        let res = await post(url, data, '乐收赢_余额退款(分账退款)');
        if (res.return_code == 'SUCCESS' && res?.result_code == 'PAY_SUCCESS') {
            return {code:0,msg:'退款成功'};
        } else {
            return {code:1,msg:res.return_msg};
        }
    } catch (error) {
        return {code:1,msg:error.message};
    }
}


/**
 * 退款
 * @param {*} refund_trace_no  退款流水号
 * @param {*} amount 退款金额 单位分
 * @param {*} org_pay_trace_no 原支付流水号
 * @returns 
 */
async function refund(refund_trace_no,amount,org_pay_trace_no) {
    let url = `${baseUrl}/v3/refundorder`;
    const data = {
        inst_no,
        mch_no: main_mch_no,
        refund_trace_no,
        refund_fee: amount,
        pay_time: moment().format('YYYYMMDDHHmmss'),
        pay_trace_no: org_pay_trace_no,
        notify_url: `${config.pay_notify_url}/api/lsy/refund/notify`, //回调地址
    };
    let sign = makeSign(data);
    data.sign = sign;
    try {
        let res = await post(url, data, '乐收赢_退款');
        if (res.return_code == 'SUCCESS' && res.result_code == 'PAY_SUCCESS') {
            return {code:0,msg:'退款成功'};
        }else if(res.return_code=='SUCCESS' && res.result_code=='PAY_IN_PROCESS') {
            console.log('退款处理中', res.return_msg, '入参:', data);
            return {code:2,msg:'退款处理中'};
        } else {
            console.error('退款失败', res.return_msg, '入参:', data, '响应:', res);
            return {code:1,msg:res.return_msg};
        }
    } catch (error) {
        console.error('退款失败', error.message, '入参:', data);
        return {code:1,msg:error.message};
    }
}

/**
 * 查询退款状态
 * @param {string} refund_trace_no 退款流水号
 * @returns {Promise<Object>} 返回退款状态结果
 */
async function refundStatus(refund_trace_no) {
    let url = `${baseUrl}/v3/queryrefund`;
    const data = {
        inst_no,
        mch_no: main_mch_no,
        query_trace_no: uuidv4().replace(/-/g, ''),
        refund_trace_no
    };
    let sign = makeSign(data);
    data.sign = sign;
    try {
        let res = await post(url, data, '乐收赢_退款状态查询');
        if (res.return_code == 'SUCCESS' && res.result_code != 'PAY_FAIL') {
            return {code: 0, msg: '退款成功'};
        } else {
            console.error('退款状态查询失败', res.return_msg, '入参:', data, '响应:', res);
            return {code: 1, msg: res.return_msg};
        }
    } catch (error) {
        console.error('退款状态查询失败', error.message, '入参:', data);
        return {code: 1, msg: error.message};
    }
}

//提现
async function merchantWithdraw(refund_trace_no ) {

    const realParams = {
        inst_no,
        mch_no: main_mch_no,
        pay_trace_no,
        total_amount,
        into_type: 'DM'
  
    };
    realParams.sign = makeSign(realParams);
    return await post(baseUrl + '/v3/enchash', realParams, '商户余额提现');
}
//查询商户余额
async function getMerchantBalance(mch_no) {
    const realParams = {
        pay_trace_no: uuidv4().replace(/-/g, ''),
        inst_no,
        mch_no
    };
    realParams.sign = makeSign(realParams, inst_key);
    let res = await post(baseUrl + '/v3/balanceQuerry', realParams, '商户余额查询');
    if (res.return_code == 'SUCCESS' ) {
        return {code:0,msg:'查询成功',balance:res.total_balance};
    } else {
        return {code:1,msg:res.return_msg};
    }
}
/**
 * 查询商户结算
 */
async function getMerchantSettlement(params) {
    const realParams = {
        ...params,
        inst_no,
        bd_id: '735',
    };
    realParams.sign = makeSign(realParams, CONFIG.INST_KEY);
    return await post(`${baseUrl}` + '/opensettle/page', realParams, '商户结算查询');
}

export default {
    applet_pay,
    balancePay,
    balancePayStatus,
    balancePayRefund,
    refund,
    refundStatus,
    merchantWithdraw,
    getMerchantBalance,
    generateTraceNo
}

// getMerchantBalance(main_mch_no).then(res => {
//     console.log('商户余额:', res);
// }).catch(err => {
//     console.error('查询商户余额出错:', err);
// });

//  refund('20231009123456789012', 100,'20250426112558333623016' )
// refundStatus('202310091234567890124').then(res => {
//     console.log('退款状态:', res);
// }).catch(err => {
//     console.error('查询退款状态出错:', err);
// });

// balancePay(main_mch_no, '20231009123456789012654', [{ share_mch: '852504260027', share_amount: 20 },{ share_mch: '852504260034', share_amount: 10 }], 30,'附加数据')
//     .then(res => {
//         console.log('余额支付结果:', res);
//     })
//     .catch(err => {
//         console.error('余额支付出错:', err);
//     });

// applet_pay(moment().unix(),'852505050001', 100, 'o8jTE5bJ4vvY5wOnL0ZMTxVbHkkk', '测试订单')
//     .then(res => {
//         console.log('支付结果:', res);
//     })
//     .catch(err => {
//         console.error('支付出错:', err);
//     });